package paper.db;

import java.util.HashSet;
import java.util.Iterator;
import java.sql.*;

import paper.db.DB;

public class GarbageCollect {

    // at present this just identifies garbage - in a very slow manner!
    // needs to actually remove all papers with active = 0, and more important,
    // all citations with active = 0.

    GarbageCollect() {
    }

    private void gc(boolean delete) {
        try {
            Statement st = DB.connection.createStatement();
            st.executeUpdate("UPDATE papers SET active=0");
            st.executeUpdate("UPDATE flattitles SET active=0");
            st.executeUpdate("UPDATE citations SET active=0");
            //st.executeUpdate("UPDATE pdffiles SET active=0");
            int i = st.executeUpdate("UPDATE papers SET active=1 FROM pdffiles f WHERE f.active<>0 AND f.paperkey=papers.key");
            int a = 0, b = 0, c = 0, d = 0;
            for (int j = 0; j < 10; j++) {
                a = st.executeUpdate("UPDATE citations SET active=1 FROM papers p WHERE citations.active=0 AND citations.paper = p.key AND p.active=1");
                b = st.executeUpdate("UPDATE papers SET active=2 WHERE active=1");
                c = st.executeUpdate("UPDATE papers SET active=1 FROM citations c WHERE c.cites = papers.key AND c.active=1 AND papers.active=0");
                d = st.executeUpdate("UPDATE citations SET active=2 WHERE active=1");
                if (a+b+c+d == 0) {
                    if (delete) {
                        a = st.executeUpdate("DELETE FROM citations WHERE active=0");
                        b = st.executeUpdate("DELETE FROM papers WHERE active=0 AND key LIKE '%-%'");
                        c = st.executeUpdate("DELETE FROM papers WHERE active=0");
                        System.out.println("Garbage collection: found " + a +
                                           " dead references and " + c +
                                           " dead papers");
                    }
                    return;
                }
            }
            System.out.println("GC failed to converge, " + a + " " + b + " " + c + " " + d);
        } catch (Exception e) {
            System.err.println("Caught " + e);
        }
    }

    public static void main(String args[]) {
        GarbageCollect n = new GarbageCollect();
        n.gc(args.length > 0);
    }
}
